package com.panfeng.xcloud.component.sms;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.google.common.base.Preconditions;
import com.panfeng.xcloud.component.sms.config.ChuangLanSmsProp;
import com.panfeng.xcloud.component.sms.config.ChuangLanVoiceCodeProp;
import com.panfeng.xcloud.component.sms.config.MultiSmsPropConfig;
import com.panfeng.xcloud.component.sms.constants.MultiSmsConstants;
import com.panfeng.xcloud.component.sms.enums.SMSChannelTypeEnum;
import com.panfeng.xcloud.component.sms.model.VoiceCodeReqDTO;
import com.panfeng.xcloud.component.sms.model.VoiceCodeRespDTO;
import com.panfeng.xcloud.component.sms.template.SMSTemplate;
import com.panfeng.xcloud.component.sms.utils.ChuangLanSmsUtil;
import com.panfeng.xcloud.component.sms.utils.HttpVoiceVerCodeSender;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Set;

/**
 * 阿里云短信服务(蓝创语音验证)
 *
 * @author xiaobo
 * @date 2018-02-07
 */
@Slf4j
@Component
public class SMSMsgSender {

    @Autowired
    private MultiSmsPropConfig multiSmsPropConfig;

    public VoiceCodeRespDTO voiceSendAndGet(VoiceCodeReqDTO voiceCodeReqDTO){
        log.info(">>> 发送语音验证码参数：{} <<<",(null != voiceCodeReqDTO ? JSON.toJSONString(voiceCodeReqDTO):""));
        VoiceCodeRespDTO voiceCodeRespDTO = new VoiceCodeRespDTO();
        voiceCodeRespDTO.setMobileNo(voiceCodeReqDTO.getMobileNo());
        voiceCodeRespDTO.setVoiceCodeBizType(voiceCodeReqDTO.getVoiceCodeBizType());
        ChuangLanVoiceCodeProp chuangLanVoiceCodeProp = multiSmsPropConfig.getChuangLanVoiceCodeProp();
        String url = chuangLanVoiceCodeProp.getUrl();
        String account = chuangLanVoiceCodeProp.getAccount();
        String pswd = chuangLanVoiceCodeProp.getPassword();
        String mobile = voiceCodeReqDTO.getMobileNo();
        String msg = voiceCodeReqDTO.getContent();
        try {
            String returnString = HttpVoiceVerCodeSender.batchSend(url, account, pswd, mobile, msg, true, null);
            voiceCodeRespDTO.setRespContent(returnString);
            log.info(">>>> 给手机号：{} 发送语音验证码内容：{} <<",voiceCodeReqDTO.getMobileNo(),voiceCodeReqDTO.getContent());
            if(StringUtils.isNotEmpty(returnString)){
                if(returnString.indexOf(",") != -1 && returnString.split(",").length >= 2){
                    //@TODO:returnString 格式：20191118143119,101
                    String returnCode = "";
                    if(returnString.indexOf("\n") != -1){
                        returnCode = returnString.split(",")[1].split("\n|\r")[0];
                    }else{
                        returnCode = returnString.split(",")[1];
                    }
                    voiceCodeRespDTO.setIsOk("0".equalsIgnoreCase(returnCode));
                }else{
                    voiceCodeRespDTO.setIsOk(false);
                }
            }else{
                voiceCodeRespDTO.setIsOk(false);
            }
        } catch (Exception e) {
            log.info(">>>> 发送语音验证码内容异常：{}",e.getMessage());
            e.printStackTrace();
            voiceCodeRespDTO.setIsOk(false);
        }
        log.info(">>>> 给手机号：{} 发送语音验证码响应内容：{} <<",voiceCodeReqDTO.getMobileNo(),JSON.toJSONString(voiceCodeRespDTO));
        return voiceCodeRespDTO;
    }

    public boolean sendAndGet(SMSTemplate smsTemplate) {
        Preconditions.checkArgument(StringUtils.isNotEmpty(smsTemplate.getMobile()), "手机号不能为空");
        Preconditions.checkArgument(StringUtils.isNotEmpty(smsTemplate.getContext()), "短信内容不能为空");

        //判断短信通道类型，判断是阿里云的短信通道还是蓝创的短信通道
        Byte smsChannelType = multiSmsPropConfig.getSmsChannelType();
        if (smsChannelType == SMSChannelTypeEnum.LANCHUANG.getValue()){
            ChuangLanSmsProp chuangLanSmsProp = multiSmsPropConfig.getChuangLanSmsProp();
            String contextJsonString = smsTemplate.getContext();
            JSONObject contextJsonObj = JSONObject.parseObject(contextJsonString);
            String template = smsTemplate.getTemplate();

            Set<Map.Entry<String, Object>> entries = contextJsonObj.entrySet();

            for (Map.Entry<String, Object> contextItem : entries){
                String key = contextItem.getKey();
                Object value = contextItem.getValue();
                template = template.replace("${"+key+"}",value.toString());
            }

            JSONObject smsSendContentObj = new JSONObject();

            smsSendContentObj.put("account",chuangLanSmsProp.getAccount());
            smsSendContentObj.put("password",chuangLanSmsProp.getPassword());
            smsSendContentObj.put("msg",template);
            smsSendContentObj.put("phone",smsTemplate.getMobile());

            String smsContentJsonString = smsSendContentObj.toJSONString();

            log.info("创蓝短信服务-短信发送内容，手机号：{}，发送内容：{}", smsTemplate.getMobile(), smsContentJsonString);

            String response = ChuangLanSmsUtil.sendSmsByPost(chuangLanSmsProp.getUrl(), smsContentJsonString);
            if (StringUtils.isEmpty(response)){
                log.error(">>> 蓝创短信服务响应为空 <<<");
                return false;
            }
            JSONObject resultJsonObj = JSON.parseObject(response);
            if (!MultiSmsConstants.CHUANGLAN_SUCCESS_CODE.equals(resultJsonObj.get(MultiSmsConstants.CHUANGLAN_CODE))) {
                log.error(">>> 蓝创短信服务异常，错误码为：{},错误描述：{} <<<", resultJsonObj.getString("code"),resultJsonObj.get("errorMsg"));
                return false;
            }
            return true;
        }else{
            //可自助调整超时时间
            System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
            System.setProperty("sun.net.client.defaultReadTimeout", "10000");

            //初始化acsClient,暂不支持region化
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", multiSmsPropConfig.getAliyunSmsProp().getAccessKey(), multiSmsPropConfig.getAliyunSmsProp().getSecretKey());
            try {
                DefaultProfile.addEndpoint("cn-hou", "cn-hangzhou", MultiSmsConstants.ALIYUN_PRODUCT, MultiSmsConstants.ALIYUN_DOMAIN);
            } catch (ClientException e) {
                log.error("阿里云短信服务-初始化阿里云短信SDK异常", e);
                e.printStackTrace();
                return false;
            }
            IAcsClient acsClient = new DefaultAcsClient(profile);

            //组装请求对象-具体描述见控制台-文档部分内容
            SendSmsRequest request = new SendSmsRequest();
            //必填:待发送手机号
            request.setPhoneNumbers(smsTemplate.getMobile());

            //必填:短信签名-可在短信控制台中找到
            request.setSignName(smsTemplate.getSignName());

            //必填:短信模板-可在短信控制台中找到
            request.setTemplateCode(multiSmsPropConfig.getChannels().get(smsTemplate.getTemplate()));

            //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"
            request.setTemplateParam(smsTemplate.getContext());
            request.setOutId(smsTemplate.getMobile());

            try {
                SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
                log.info("阿里云短信服务-短信发送完毕，手机号：{}，返回状态：{}", smsTemplate.getMobile(), sendSmsResponse.getCode());
                if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
                    return true;
                }
            } catch (ClientException e) {
                log.error("阿里云短信服务-发送短信异常",e);
                e.printStackTrace();
                return false;
            }
            return false;
        }
    }

}
